package restaurant.gui;

import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

/**
 * The Class ViewMenuDialog.
 */
@SuppressWarnings("serial")
public class ViewMenuDialog extends JDialog implements ActionListener,
		PropertyChangeListener
{
	/** The PRICE constant. */
	protected final static int PRICE = 1;

	/** The PREP constant. */
	protected final static int PREP = 2;

	/** The RATING constant. */
	protected final static int RATING = 3;

	/** The AVAIL constant. */
	protected final static int AVAIL = 4;

	/** The text typed in the dialog box. */
	private String typedText = null;

	/** The text field placed in the dialog box. */
	private JTextField textField;

	/** The option pane. */
	private JOptionPane optionPane;

	/** The choice of the type of dialog box created. */
	private int choice;

	/** The button string 1. */
	private String btnString1 = "Enter";

	/** The button string 2. */
	private String btnString2 = "Cancel";



	/**
	 * Returns null if the typed string was invalid; otherwise, returns the
	 * string as the user entered it.
	 * 
	 * @return the validated text
	 */
	public String getValidatedText()
	{
		return typedText;
	}



	/**
	 * Creates the reusable dialog.
	 * 
	 * @param frame the owner of the dialog box.
	 * @param message the message to be displayed in the dialog box.
	 * @param title the title of the dialog box.
	 * @param choice the choice of the type of dialog box.
	 */
	public ViewMenuDialog(Frame frame, String message, String title, int choice) {
		super(frame, true);

		setTitle(title);
		this.choice = choice;

		textField = new JTextField(10);

		Object[] array = { new JLabel(message), textField };
		Object[] options = { btnString1, btnString2 };

		// Create the JOptionPane.
		optionPane = new JOptionPane(array, JOptionPane.QUESTION_MESSAGE,
				JOptionPane.YES_NO_OPTION, Restaurant.QUESTION_ICON, options,
				options[0]);
		setContentPane(optionPane);
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

		addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent we)
			{
				optionPane.setValue(new Integer(JOptionPane.CLOSED_OPTION));
			}
		});

		// Ensure the text field always gets the first focus.
		addComponentListener(new ComponentAdapter() {
			public void componentShown(ComponentEvent ce)
			{
				textField.requestFocusInWindow();
			}
		});

		textField.addActionListener(this);
		optionPane.addPropertyChangeListener(this);
	}



	/**
	 * The event handler that puts the text into the option pane.
	 * 
	 * @param e the action event.
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e)
	{
		optionPane.setValue(btnString1);
	}



	/**
	 * The event handler that reacts to option pane state changes.
	 * 
	 * @param e the action event.
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent e)
	{
		String prop = e.getPropertyName();

		if (isVisible() &&
				(e.getSource() == optionPane) &&
				(JOptionPane.VALUE_PROPERTY.equals(prop) || JOptionPane.INPUT_VALUE_PROPERTY
						.equals(prop))) {
			Object value = optionPane.getValue();

			if (value == JOptionPane.UNINITIALIZED_VALUE) {
				// ignore reset
				return;
			}

			optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);

			if (btnString1.equals(value)) {
				typedText = textField.getText();

				// Determine if the input is an integer
				try {
					int valueEntered = Integer.parseInt(typedText);
					boolean invalid = false;

					// Switch statement to ensure the number entered is in the
					// correct range based on the type of dialog box
					switch (choice) {
					case PRICE:
						if (valueEntered < 10 || valueEntered > 100) {
							invalid = true;
							showDialog(" between 10 and 100");
						}
						break;
					case PREP:
						if (valueEntered < 10 || valueEntered > 60) {
							invalid = true;
							showDialog(" between 10 and 60");
						}
						break;
					case RATING:
						if (valueEntered < 0 || valueEntered > 5) {
							invalid = true;
							showDialog(" between 0 and 5");
						}
						break;
					case AVAIL:

						break;
					default:
						break;
					}

					if (invalid == false)
						clearAndHide();
				}
				catch (NumberFormatException nfe) {
					showDialog("");
				}
			}
			else {
				typedText = null;
				clearAndHide();
			}
		}
	}



	/**
	 * Shows the dialog box.
	 * 
	 * @param range the range of valid input for the field.
	 */
	private void showDialog(String range)
	{
		// text was invalid
		textField.selectAll();
		JOptionPane.showMessageDialog(ViewMenuDialog.this, "Sorry, \"" +
				typedText + "\" " + "isn't a valid response.\n" +
				"Please enter a positive integer" + range + ".", "Try again",
				JOptionPane.ERROR_MESSAGE, Restaurant.ERROR_ICON);
		typedText = null;
		textField.requestFocusInWindow();
	}



	/**
	 * Hides the dialog box.
	 */
	public void clearAndHide()
	{
		textField.setText(null);
		setVisible(false);
	}

}
